package com.cskaoyan.javase.oop3._3inner._1member._1basic;

import sun.management.snmp.jvminstr.JvmThreadInstanceEntryImpl;

/**
 * 在具体讲解访问特点之前,我们还是要明确两个特点:
 * 1.成员内部类和它的外围类是好兄弟,它们互相访问成员,都不受访问权限限制.
 * 2.成员内部类对象,要依赖于外围类对象存在.这意味着:
 *      a.成员内部类当中的成员方法中,有几个对象存在?
 *          首先肯定隐含自身对象,用this指向
 *          而且还隐含外围类对象,用外围类类名.this指向
 *     b.成员内部类当中的静态成员方法中,有几个对象存在?
 *     成员内部类没有静态声明,这是坑你的题目
 *
 *     c.外围类的成员方法中,隐含有几个对象?
 *      只有一个对象,那就是this指向外围类自身对象
 *      成员内部类对象要想创建,必须在外围类对象的基础上创建
 *      这时,既然没有成员内部类对象,那怎么得到这个成员内部类对象?
 *      既然外围类对象已经存在,就直接创建成员内部类对象就可以,直接new就完事了.
 *
 *      d.外围类的静态成员方法中,隐含有几个对象?
 *      没有隐含对象
 *      这时,既然没有成员内部类对象,那怎么得到这个成员内部类对象?
 *      要先创建外围类对象,再在外围类对象的基础上创建成员内部类对象.
 *
 * 成员内部类的访问特点，主要从以下几个角度研究：
 * 1. 成员内部类内部访问外围类成员
 *      首先,访问肯定是在成员内部类的成员方法中进行的
 *      这时想要访问外围类成员,因为对象已经存在,就可以直接访问了.
 *      如果出现同名成员,用不同引用指向访问即可.
 *      如果出现同名全局常量,用类名区分
 *
 * 2. 外围类访问成员内部类成员
 *      1.在外围类中的成员方法
 *          因为外围类对象已经存在,直接new成员内部类对象即可.访问成员用对象名点就可以访问了.
 *
 *      2.在外围类中的静态成员方法
 *          没有外围类对象,所以先new外围类对象
 *          再new成员内部类对象
 *          这时用谁的对象名访问,就是谁的成员
 *
 * 3. 外部类访问成员内部类成员
 *      先创建外围类对象,再创建成员内部类对象
 *      但是要注意,要考虑访问权限的问题,它们不是好兄弟了,要受权限控制
 *      在外部类中不管是静态方法还是成员方法,没有区别
 *      不管你隐含谁的对象,反正和我内部类没关系
 *
 * 4. 成员内部类访问外部类成员
 *      只要创建它的对象,就可以直接访问了
 *      受访问权限限制
 *
 *
 * @since 16:55
 * @author wuguidong@cskaoyan.onaliyun.com
 */
public class Demo {
    public static void main(String[] args) {
        EnclosedClazz ec = new EnclosedClazz();
        // 这里要明确指出,成员内部类属于哪个外围类
        EnclosedClazz.InnerClazz ic = ec.new InnerClazz();

        //上述代码还是可以二合一
        EnclosedClazz.InnerClazz ic2 = new EnclosedClazz().new InnerClazz();
        // ic.b;

    }

    public void test() {

    }
}

// 外围类
class EnclosedClazz {
    int a;
    private int b = 200;
    static final int C = 300;
    static final String D = "hello";

    public void testEnclosed() {
        InnerClazz ic = new InnerClazz();
        // 上述代码补全
        // 这叫做在外围类对象的基础上,创建成员内部类对象
        InnerClazz ic2 = this.new InnerClazz();
        System.out.println(ic.a);
        System.out.println(ic.b);
    }

    public static void testStatic() {
        EnclosedClazz ec = new EnclosedClazz();
        InnerClazz ic = ec.new InnerClazz();

        //上述代码二合一
        // 这叫做在外围类对象的基础上,创建成员内部类对象
        InnerClazz ic2 = new EnclosedClazz().new InnerClazz();
    }

    // 定义成员内部类
    class InnerClazz {
        int a;
        private int b = 20;
        static final int C = 30;
        static final String D = "123";

        // 成员内部类的成员方法
        /*
            首先肯定隐含自身对象,用this指向
            而且还隐含外围类对象,用外围类类名.this指向
         */
        public void test() {
            System.out.println(a);
            System.out.println(b);
            System.out.println(EnclosedClazz.this.a);
            System.out.println(EnclosedClazz.this.b);
            System.out.println(C);
            System.out.println(EnclosedClazz.C);
        }

        public InnerClazz(int a, int b) {
            this.a = a;
            this.b = b;
        }

        public InnerClazz() {
        }
    }
}